package com.aries.dubbo.like.rpc.client.util;

import com.aries.dubbo.like.rpc.client.MatchUtil;
import com.aries.dubbo.like.rpc.common.ResponseWrapper;
import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * Created with IntelliJ IDEA.
 * Author: aries
 * Date: 2018/8/23
 * Description: 定时清除map中的过期元素，防止oom或者内存泄漏，30秒执行一次。
 */
@Slf4j
public class TimeOutResponseJob {
    //20秒
    private static final Long timeout = 20000L;
    private static ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(2);

    public static void start() {
        scheduledExecutorService.scheduleWithFixedDelay(() -> {
            Long current = System.currentTimeMillis();
            log.info("TimeOutResponseJob start");
            log.info("before delete,map has " + MatchUtil.getMap().size() + " entities.");
            ConcurrentHashMap<String, ResponseWrapper> map = MatchUtil.getMap();
            //移除已经使用完了的和已经超时的请求，防止内存溢出以及内存泄漏
            map
                    .entrySet()
                    .removeIf(stringResponseWrapperEntry ->
                            stringResponseWrapperEntry.getValue().isDone()
                                    && current - stringResponseWrapperEntry.getValue().getRequestTime() >= timeout
                    );
            log.info("after delete, map has " + MatchUtil.getMap().size() + " entities.");
        }, 20, 30, TimeUnit.SECONDS);
    }
}
